#include "StdAfx.h"


CMainCamera::CMainCamera(void)
{
	m_pState=NULL;
	m_pPlayer=NULL;

	m_CameraRotationX=PI/8;	
	m_CameraRotationY=PI-PI/4;	
	m_CameraDistance=8;
}

CMainCamera::~CMainCamera(void)
{
}

bool CMainCamera::Init(CGameState * pState,CCharacter * pPlayer)
{
	m_pState=pState;

	CD3DMatrix Mat;
	Mat.SetTranslation(CD3DVector3(0,0,-m_CameraDistance));
	Mat*=CD3DMatrix::FromRotationX(m_CameraRotationX)*CD3DMatrix::FromRotationY(m_CameraRotationY);
	SetLocalMatrix(Mat);
	SetProjectPerspective(D3DX_PI*47/180,CMainConfig::GetInstance()->GetScreenRate(),0.2f,500.0f);
	SetPlayer(pPlayer);

	return true;
}

void CMainCamera::SetPlayer(CCharacter * pPlayer)
{
	m_pPlayer=pPlayer;
	CD3DDummy * pDummy=m_pPlayer->EnableAttachment(CAI_TOP_OF_HEAD);
	SetParent(pDummy);
}

void CMainCamera::Update(FLOAT Time)
{
	if(m_pState&&m_pPlayer)
	{

		if(m_pPlayer)
		{
			if(m_pPlayer->GetRotateStatus()>RS_STOP)
			{	
				if(fabs(fabs(m_CameraRotationY)-PI)>PI/50)
				{
					if(fabs(m_CameraRotationY)>PI)
						m_CameraRotationY=m_CameraRotationY-(m_CameraRotationY/fabs(m_CameraRotationY))*PI/50;
					else
						m_CameraRotationY=m_CameraRotationY+(m_CameraRotationY/fabs(m_CameraRotationY))*PI/50;
				}
			}
		}



		CD3DMatrix LocalMat=CD3DMatrix::FromTranslation(CD3DVector3(0,0,-m_CameraDistance));

		LocalMat*=CD3DMatrix::FromRotationX(m_CameraRotationX)*CD3DMatrix::FromRotationY(m_CameraRotationY);


		CD3DVector3 P1=GetParent()->GetWorldMatrix().GetTranslation();
		CD3DMatrix GlobalMat=LocalMat*GetParent()->GetWorldMatrix();
		CD3DVector3 P2=GlobalMat.GetTranslation();
		CD3DVector3 P;
		FLOAT D=m_CameraDistance;
		FLOAT A;

		if(m_pState->GetSceneRender()->LineIntersect(P1,P2,P,D,A,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA))
		{		
			LocalMat=CD3DMatrix::FromTranslation(CD3DVector3(0,0,-D));
			LocalMat*=CD3DMatrix::FromRotationX(m_CameraRotationX)*CD3DMatrix::FromRotationY(m_CameraRotationY);
			GlobalMat=LocalMat*GetParent()->GetWorldMatrix();
		}

		CD3DMatrix ViewPrjMat=GlobalMat.GetInverse()*GetProjectMat();
		ViewPrjMat.Invert();

		CD3DVector3 N1(1,1,0);
		CD3DVector3 N2(-1,1,0);
		CD3DVector3 N3(1,-1,0);
		CD3DVector3 N4(-1,-1,0);

		N1*=ViewPrjMat;
		N2*=ViewPrjMat;
		N3*=ViewPrjMat;
		N4*=ViewPrjMat;

		FLOAT D1=0;
		FLOAT D2=0;
		FLOAT D3=0;
		FLOAT D4=0;
		FLOAT A1=0,A2=0,A3=0,A4=0;

		//2--3--1
		//|     |
		//1     2
		//|     |
		//4--4--3
		m_pState->GetSceneRender()->LineIntersect(N4,N2,P,D1,A1,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
		m_pState->GetSceneRender()->LineIntersect(N3,N1,P,D2,A2,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
		m_pState->GetSceneRender()->LineIntersect(N2,N1,P,D3,A3,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
		m_pState->GetSceneRender()->LineIntersect(N4,N3,P,D4,A4,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);

		while(D1+D2+D3+D4!=0&&D>0)
		{
			D-=0.1;

			LocalMat=CD3DMatrix::FromTranslation(CD3DVector3(0,0,-D));
			LocalMat*=CD3DMatrix::FromRotationX(m_CameraRotationX)*CD3DMatrix::FromRotationY(m_CameraRotationY);
			GlobalMat=LocalMat*GetParent()->GetWorldMatrix();

			ViewPrjMat=GlobalMat.GetInverse()*GetProjectMat();
			ViewPrjMat.Invert();	
			N1=CD3DVector3(1,1,0)*ViewPrjMat;
			N2=CD3DVector3(-1,1,0)*ViewPrjMat;
			N3=CD3DVector3(1,-1,0)*ViewPrjMat;
			N4=CD3DVector3(-1,-1,0)*ViewPrjMat;

			D1=0;
			D2=0;
			D3=0;
			D4=0;		

			m_pState->GetSceneRender()->LineIntersect(N4,N2,P,D1,A1,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
			m_pState->GetSceneRender()->LineIntersect(N3,N1,P,D2,A2,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
			m_pState->GetSceneRender()->LineIntersect(N2,N1,P,D3,A3,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
			m_pState->GetSceneRender()->LineIntersect(N4,N3,P,D4,A4,NULL,RITM_INCLUDE_COLLIDE_ONLY_FACE|RITM_CAMERA);
		}	

		SetLocalMatrix(LocalMat);	
	}
	CD3DCamera::Update(Time);
}